/******************************************************
* drv_l2_sensor.h
*
* Purpose: Sensor layer 2 header file
*
* Author: Eugene Hsu
*
* Date: 2014/08/25
*
* Copyright Generalplus Corp. ALL RIGHTS RESERVED.
*
* Version :
* History :
*
*******************************************************/
#ifndef DRV_L2_SENSOR_H
#define DRV_L2_SENSOR_H
#include "project.h"
#include "driver_l1_cfg.h"


/*********************************************************************
        Structure, enumeration and definition
**********************************************************************/
#define _DRV_L2_SENSOR	_DRV_L2_CDSP	//_DRV_L1_CSI

/* Support 1 sensor in platform */
#define MAX_SENSOR_NUM			1
#define MAX_INFO_NUM			1

#define SENSOR_FLIP				1

// 1: CSI use as Front
// 0: CSI use as rear
#define _SENSOR_CSI_FRONT		0

/* Select Init Sensor */
#define _TVIN_TVP5150_CSI				0
#define _TVIN_VC0705_CSI				0
#define _SENSOR_OV7670_CSI				0

#define _SENSOR_OV7670_CDSP				0
#define _SENSOR_GC1004_CDSP_MIPI		0
#define _SENSOR_GC1014_CDSP_DVP			0
#define _SENSOR_GC1014_CDSP_MIPI		0
#define _SENSOR_GC1034_CDSP_MIPI		0
#define _SENSOR_GC1054_CDSP_MIPI		0
#define _SENSOR_GC1064_CDSP_MIPI		0
#define _SENSOR_GC1603_CDSP_MIPI		0
#define _SENSOR_JXH22_CDSP_MIPI			0
#define _SENSOR_JXH22_CDSP_DVP			0
#define _SENSOR_JXH42_CSI_MIPI			0
#define _SENSOR_JXH42_CDSP_MIPI			0
#define _SENSOR_JXH42_CDSP_DVP			0
#define _SENSOR_JXH62_CDSP_MIPI			0
#define _SENSOR_JXH65_CDSP_MIPI			0
#define _SENSOR_SP140A_CDSP_MIPI		0
#define _SENSOR_OV9750_CDSP_MIPI		0


/*ISP Pin Position Configuration*/
#define CLKO__IOC9								0x00006661
#define CLKO__IOD7								0x00006662
#define CLKO__IOD12								0x00006663
#define CLKO__IOC9_DIV2							0x00016661
#define CLKO__IOD7_DIV2							0x00016662
#define CLKO__IOD12_DIV2						0x00016663
#define ISP_CLKI_HSYNC_VSYNC__IOC8_IOC10_IOC11	0x00006664
#define ISP_CLKI_HSYNC_VSYNC__IOD6_IOD8_IOD9	0x00006665
#define CSI_CLKI_HSYNC_VSYNC__IOC8_IOC10_IOC11	0x00016664
#define CSI_CLKI_HSYNC_VSYNC__IOD6_IOD8_IOD9	0x00016665
#define ISP_DATA2_9__IOC0_7						0x00006666
#define ISP_DATA2_9__IOB8_15					0x00006667
#define ISP_DATA2_9__IOE0_7						0x00006668
#define CSI_DATA2_9__IOC0_7						0x00016666
#define CSI_DATA2_9__IOB8_15					0x00016667
#define CSI_DATA2_9__IOE0_7						0x00016668
#define ISP_DATA0_1__IOB7_6						0x00006669
#define ISP_DATA0_1__IOB5_4						0x0000666a
#define ISP_DATA0_1__IOC13_12					0x0000666b


typedef enum
{
	MCLK_NONE,
	MCLK_12M,
	MCLK_13_5M,
	MCLK_24M,
	MCLK_27M,
	MCLK_48M,
	MCLK_SYSTEM_DIV2,
	MCLK_SYSTEM_DIV4
} CSI_CLK_DEF;

typedef enum
{
	WIDTH_320		= 320,
	WIDTH_640		= 640,
	WIDTH_800		= 800,
	WIDTH_1024		= 1024,
	WIDTH_1280		= 1280,
	WIDTH_1920		= 1920
} WIDTH_MODE;

typedef enum
{
	HEIGHT_240		= 240,
	HEIGHT_480		= 480,
	HEIGHT_600		= 600,
	HEIGHT_768		= 768,
	HEIGHT_720		= 720,
	HEIGHT_1080		= 1080
} HEIGHT_MODE;

typedef enum
{
	MODE_CCIR_601,
	MODE_CCIR_656,
	MODE_CCIR_HREF
} TIMING_MODE;

typedef enum
{
	MODE_NONE_INTERLACE,
	MODE_INTERLACE
} INTERLACE_MODE;

typedef enum
{
	MODE_ACTIVE_LOW,
	MODE_ACTIVE_HIGH
} HVSYNC_MODE;

// sensor format is LSB to MSB
typedef enum
{
	V4L2_PIX_FMT_RGB565,
	V4L2_PIX_FMT_YUYV,
	V4L2_PIX_FMT_YVYU,
	V4L2_PIX_FMT_UYVY,
	V4L2_PIX_FMT_VYUY,
	V4L2_PIX_FMT_SBGGR8,				//5
	V4L2_PIX_FMT_SGBRG8,
	V4L2_PIX_FMT_SGRBG8,
	V4L2_PIX_FMT_SRGGB8,
	V4L2_PIX_FMT_SGRBG10,
	V4L2_PIX_FMT_SRGGB10,				//10
	V4L2_PIX_FMT_SBGGR10,
	V4L2_PIX_FMT_SGBRG10,
	V4L2_PIX_FMT_MAX
} SENSOR_FORMAT;

typedef enum
{
	SENSOR_PATH_CDSP,
	SENSOR_PATH_CSI
} SENSOR_PATH;

typedef enum
{
	SENSOR_SOURCE_DVP,		//parallel
	SENSOR_SOURCE_MIPI
} SENSOR_SOURCE;

typedef enum
{
	YUV,
	RAW
} SEN_DATA_FORMAT;

typedef enum {
	SENSOR_SET_H_FLIP,
	SENSOR_SET_V_FLIP,
	SENSOR_SET_DENOISE,
	SENSOR_SET_MAX
} SENSOR_CTRL;

typedef struct drv_l2_sensor_info_s
{
	INT32U	mclk;						/* master clock */
	INT32U	input_format;				/* input format */
	INT32U	output_format;				/* output format */
	INT32U	sensor_fps;					/* FPS in sensor */
	INT16U	target_w;					/* sensor width */
	INT16U	target_h;					/* sensor height */
	INT16U	sensor_w;					/* sensor width */
	INT16U	sensor_h;					/* sensor height */
	INT16U	hoffset;					/* sensor h offset */
	INT16U	voffset;					/* sensor v offset */
	INT8U	interface_mode;				/* input interface, HREF CCIR601 and CCIR656 */
	INT8U	interlace_mode;				/* interlace mode */
	INT8U	hsync_active;				/* hsync pin active level */
	INT8U	vsync_active;				/* vsync pin active level */
} drv_l2_sensor_info_t;

typedef struct drv_l2_sensor_ops_s
{
	SENSOR_SOURCE sensor_source;
	SENSOR_PATH sensor_path;
	void	(*init) (void);
	void	(*uninit) (void);
	void	(*stream_start) (INT32U index, INT32U bufA, INT32U bufB);
	void 	(*stream_stop) (void);
	INT32S	(*stream_set_ctrl)(INT32U cmd, INT32U* value);
	INT32S	(*stream_get_ctrl)(INT32U cmd, INT32U* value);
	void	(*exposure_set_freq) (INT8U num);
	drv_l2_sensor_info_t*	(*get_info)(INT32U index);
	drv_l2_sensor_info_t	info[MAX_INFO_NUM];
} drv_l2_sensor_ops_t;

typedef struct sensor_frame_range_s
{
	INT32U	point_x;
	INT32U	point_y;
	INT32U	frame_w;
	INT32U	frame_h;
	INT32U	clip_w;
	INT32U	clip_h;
	INT32U	scaledown_w;
	INT32U	scaledown_h;
	INT8U	docropflag;
	INT8U	doscaledownflag;
	INT32U	frameAddrs;
} sensor_frame_range_t;

/*********************************************************************
        External ops declaration for sensors we spport now
**********************************************************************/
#if (defined _SENSOR_OV7670_CSI) && (_SENSOR_OV7670_CSI == 1)

#if _SENSOR_CSI_FRONT
#define FRONT_SENSOR_WIDTH	720
#define FRONT_SENSOR_HEIGHT	240
#else
#define REAR_SENSOR_WIDTH	720
#define REAR_SENSOR_HEIGHT	240
#endif
extern const drv_l2_sensor_ops_t	ov7670_sensor_csi_ops;
#endif

#if ((defined _TVIN_TVP5150_CSI) && (_TVIN_TVP5150_CSI == 1)||(defined _TVIN_VC0705_CSI) && (_TVIN_VC0705_CSI == 1))
#define REAR_SENSOR_WIDTH	720
#define REAR_SENSOR_HEIGHT	240
extern const drv_l2_sensor_ops_t	tvp5150_csi_ops;
#endif

#if (defined _TVIN_GM7150_CSI) && (_TVIN_GM7150_CSI == 1)
#define REAR_SENSOR_WIDTH	688
#define REAR_SENSOR_HEIGHT	240
extern const drv_l2_sensor_ops_t	tvp5150_csi_ops;
#endif

#if (defined _SENSOR_GC0308_CSI) && (_SENSOR_GC0308_CSI == 1)
#define REAR_SENSOR_WIDTH	640
#define REAR_SENSOR_HEIGHT	480
extern const drv_l2_sensor_ops_t	gc0308_sensor_csi_ops;
#endif

#if (defined _SENSOR_OV3640_CSI) && (_SENSOR_OV3640_CSI == 1)
extern const drv_l2_sensor_ops_t	ov3640_sensor_csi_ops;
#endif

#if (defined _SENSOR_OV7670_CDSP) && (_SENSOR_OV7670_CDSP == 1)
extern const drv_l2_sensor_ops_t	ov7670_cdsp_ops;
#endif

#if (defined _SENSOR_JXH22_CDSP_MIPI) && (_SENSOR_JXH22_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	h22_cdsp_mipi_ops;
#endif

#if (defined _SENSOR_JXH22_CDSP_DVP) && (_SENSOR_JXH22_CDSP_DVP == 1)
extern const drv_l2_sensor_ops_t	jxh22_cdsp_dvp_ops;
#endif

#if (defined _SENSOR_JXH42_CDSP_MIPI) && (_SENSOR_JXH42_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	h42_cdsp_mipi_ops;

#endif

#if (defined _SENSOR_JXH42_CSI_MIPI) && (_SENSOR_JXH42_CSI_MIPI == 1)
extern const drv_l2_sensor_ops_t	h42_csi_mipi_ops;
#endif

#if (defined _SENSOR_JXH42_CDSP_DVP) && (_SENSOR_JXH42_CDSP_DVP == 1)
extern const drv_l2_sensor_ops_t	h42_cdsp_dvp_ops;
#endif

#if (defined _SENSOR_JXH62_CDSP_MIPI) && (_SENSOR_JXH62_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	h62_cdsp_mipi_ops;
#endif

#if (defined _SENSOR_JXH65_CDSP_MIPI) && (_SENSOR_JXH65_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	h65_cdsp_mipi_ops;
#endif

#if (defined _SENSOR_GC1004_CDSP_MIPI) && (_SENSOR_GC1004_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	gc1004_cdsp_mipi_ops;
#endif

#if (defined _SENSOR_GC1014_CDSP_DVP) && (_SENSOR_GC1014_CDSP_DVP == 1)
extern const drv_l2_sensor_ops_t	gc1014_cdsp_dvp_ops;
#endif

#if (defined _SENSOR_GC1014_CDSP_MIPI) && (_SENSOR_GC1014_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	gc1014_cdsp_mipi_ops;
#endif

#if (defined _SENSOR_GC1034_CDSP_MIPI) && (_SENSOR_GC1034_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	gc1034_cdsp_mipi_ops;
#endif

#if (defined _SENSOR_GC1054_CDSP_MIPI) && (_SENSOR_GC1054_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	gc1054_cdsp_mipi_ops;
#endif

#if (defined _SENSOR_GC1064_CDSP_MIPI) && (_SENSOR_GC1064_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	gc1064_cdsp_mipi_ops;
#endif

#if (defined _SENSOR_GC1603_CDSP_MIPI) && (_SENSOR_GC1603_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	gc1603_cdsp_mipi_ops;
#endif

#if (defined _SENSOR_SP140A_CDSP_MIPI) && (_SENSOR_SP140A_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	sp140a_cdsp_mipi_ops;
#endif

#if (defined _SENSOR_OV9750_CDSP_MIPI) && (_SENSOR_OV9750_CDSP_MIPI == 1)
extern const drv_l2_sensor_ops_t	ov9750_cdsp_mipi_ops;
#endif

/*********************************************************************
        External function declaration
**********************************************************************/

extern void	function_position_sel(INT32U mclk_pos, INT32U ctrl_pos, INT32U data_pos1, INT32U data_pos0);
extern void sensor_set_max_lum(int max_lum);
extern void sensor_csi_motion_detct_init(INT8U md_en, INT32U csi_md_buf);
extern void	drv_l2_mipi_ctrl_set_clk(INT8U mipiclk_on, INT32U mipiclk_div);

extern void	drv_l2_sensor_register_ops(const drv_l2_sensor_ops_t *sensor);
extern void	drv_l2_sensor_set_path(INT32U sen_path);
extern void	drv_l2_sensor_set_csi_source(INT32U from_mipi_en);
extern void drv_l2_sensor_init(void);
extern INT32S drv_l2_sensor_frame_range_clip(sensor_frame_range_t *frameRange);
extern INT32S drv_l2_sensor_set_mclkout(CSI_CLK_DEF mclk_sel, MASTER_CLOCK_MIPI_ENUM mipi_en, MASTER_CLOCK_CSI_ENUM csi_en);
extern const drv_l2_sensor_ops_t *drv_l2_sensor_get_ops(INT32U index);

extern INT16U drv_l2_user_sensor_width_get(void);
extern INT16U drv_l2_user_sensor_height_get(void);
extern void drv_l2_user_sensor_frequence(INT32U freq_num);
extern void drv_l2_user_sensor_csi_scale_up_set(INT8U enable);
extern void	drv_l2_user_sensor_init(INT32U isp_bufferA, INT32U isp_bufferB);

#endif //DRV_L2_SENSOR_H
